package org.happycomp.radiog.encoding;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;

public class EncodeMonitor implements IRunnableWithProgress {
	
	private boolean encodingFinished = false;
	private Lock reentrantLock = new ReentrantLock();
	
	public void run(IProgressMonitor monitor) {
		monitor.beginTask("Kodovani ", 100);
		monitor.subTask("Prekodovavam ... ");
		boolean up = true;
		while(!encodingFinished) {
			int max = 100;
			if (up) {
				up(monitor, max);
				try {
					this.reentrantLock.lock();
					if (encodingFinished) {
						monitor.done();
						return;
					}
				}finally {
					this.reentrantLock.unlock();
				}
			} else {
				down(monitor,  max);
				try {
					this.reentrantLock.lock();
					if (encodingFinished) {
						monitor.done();
						return;
					}
				}finally {
					this.reentrantLock.unlock();
				}
			}
		}
		monitor.done();
	}

	private void down(IProgressMonitor monitor,  int max) {
		for (int i = max-1; i>=0; i--) {
			try {
				this.reentrantLock.lock();
				if (encodingFinished)	{
					return;
				}
			}finally {
				this.reentrantLock.unlock();
			}
			if (monitor.isCanceled())
				return;
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			monitor.worked(i);
		}
	}

	private void up(IProgressMonitor monitor, int max) {
		for (int i = 0; i < max; i++) {
			try {
				this.reentrantLock.lock();
				if (encodingFinished)	{
					return;
				}
			} finally {
				this.reentrantLock.unlock();
			}
			if (monitor.isCanceled())
				return;
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			monitor.worked(i);
		}
	}
	
	public void setEncodingFinished(boolean encodingFinished) {
		try {
			this.reentrantLock.lock();
			this.encodingFinished = encodingFinished;
		} finally {
			this.reentrantLock.unlock();
		}
	}
	
	public Lock getReentrantLock() {
		return reentrantLock;
	}
}
